package fr.uvsq.isty.bdh.hchess.interfacing;

import ictk.boardgame.chess.ChessBoard;

/**
 * The class represents a chess player.
 * It must save the game state on its own, and is terminated if an
 * non-authorized move was made.
 * @author Clement Bellot <clementbellot@gmail.com>
 */
public interface IChessPlayer {
    /**
     * @return Whether the implementation can send text messages.
     */
    boolean sendsChat();
    /**
     * @return Whether the implementation may recive text messages.
     */
    boolean recivesChat();
    /**
     * @deprecated Should not be implemented, as this is probably not the
     * best way to do it.
     * This method will be called when a message was sent by the other player.
     * @param message The message sent by the other player.
     * @throws NotImplementedException If recivesChat() is false.
     */
    void notifyChatRecived(String message);
    /**
     * @deprecated Should not be implemented, as this is probably not the
     * best way to do it.
     * Will be called from times to times, even in getNextMove.
     * If the string was not empty, it will be called again just after.
     * @return A string with a message, or null if no new messages are sent.
     */
    String getChat();
    
    /**
     * Whether the interface can start from any position. If the method return
     * true, the method must handle the case where <code>startPos</code> is not
     * the normal chess starting.
     * @return false if it does not handles starting positions different from
     * the standard one.
     */
    boolean handlesNonStandardStarts();
    /**
     * Wether the player is able to replay a previous game to reach a 
     * certain point, and then resume the game. If this method returns true,
     * the player must handle the non empty arrays as 
     * <code>stateToRestore</code> in the setUp method.
     * @return 
     */
    boolean handlesResume();
    /**
     * Initializes the class with a non-standard position.
     * 
     * Some of the parameters can be ignored if the player cannot implement
     * them.
     * @param notifier The comunication chanel from the player to the referee.
     * If the player intends to send any, it should save it.
     * @param startPos The starting position. If the 
     * <code>handlesNonStandardStarts()</code> return false, this parameter can
     * be ignored. If the game starts with the standard position, the parameter
     * will be the standard starting position.
     * @param stateToRestore A array of moves. The player should replay the
     * given moves as if alternatively him or his oponnent played theses.
     * If the method <code>handlesNonStandardStarts()</code> return false, the
     * player can ingnore this argument. If there is no state to restore, 
     * the array will be empty.
     */
    void setUp(
            GameEventRefereeNotifier notifier,
            ChessBoard startPos,
            int[][] stateToRestore)
                throws FailedToReachPlayerException;
    /**
     * Other interface functions may be called while into this function.
     * @param lastMove The other player last move, or null if the game just
     * started. In the form 
     * [originX, originY,destX, destY,promotionTargetIndex].
     * The coordinates ranges in [1,8].
     * The promotionTargetIndex is the one in ictk.boardgame.chessChessPiece.
     * The promotionTargetIndex is not needed, and defaults to Queen.
     * Note that if the game is resuming (non-empty stateToRestore parameter),
     * the last move will be sent anyway.
     * @return The choosen move. If incorrect, the player looses with the
     * GameEvent ErroneousMove. If null, the method getEvent will be called.
     * If the event is not terminating the game, the game continues.
     */
    int[] getNextMove(int[] lastMove)
            throws FailedToReachPlayerException;
    /**
     * Called when the other player made a move that finished the game.
     * @param lastMove The other player finishing move.
     */
    void notifyFinalMove(int[] lastMove)
            throws FailedToReachPlayerException;
    /**
     * Same as getNextMove(ChessMove lastMove), but with a time limit.
     * @param timeLimit The time in seconds the player has to play the turn.
     * If timed out, the player looses. Note that the player will actually loose
     * only once the function has returned, because there are no easy way to
     * easyly terminate a function.
     */
    int[] getNextMove(int[] lastMove,int timeLimit)
            throws FailedToReachPlayerException;
    /**
     * Called when a game event happened.
     * Basically, a player won, a draw was asked...
     * @param event 
     */
    void notifyGameEvent(GameEvent event)
            throws FailedToReachPlayerException;
}
